import socket
import os
import sys
import struct

def socket_service_file():
    try :
        #建立套接字
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        
        # setsockopt()是一个用于设置套接字选项的方法。通过调用这个方法，您可以在套接字层面上对套接字进行各种配置。
        # 第一个参数 socket.SOL_SOCKET 指定了要设置选项的套接字级别，即套接字选项所处的层级。在这种情况下，它设置了 SOL_SOCKET，表示套接字选项应该在套接字层面上生效。
        # 第二个参数 socket.SO_REUSEADDR 是要设置的具体选项名称。在这种情况下，SO_REUSEADDR 表示开启地址重用选项。
        # 第三个参数 1 是要设置的选项值。在这种情况下，设置为 1 表示启用这个选项。
        
        s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
        s.bind(("192.168.0.102",6666)) #端口地地址
        s.listen(5)
    #socket.error类型的异常，当发生套接字相关的错误时，异常将被捕获
    except socket.error as msg:
        print(msg)
        sys.exit(1)
    
    print("wait for Connection-----------")
    
    while True:
        sock, addr = s.accept() #addr是一个元组(ip,port)
        deal_file(sock,addr)
        
def deal_file(sock,addr):
    print("Accopt connect from {0}".format(addr))
    
    while True:
        fileinfo_size = struct.calcsize('128sq')
        buf = sock.recv(fileinfo_size) #接收文件名
        if buf:
            filename, filesize = struct.unpack('128sq',buf)
            fn = filename.decode().strip('\x00')
            # 在服务器端新建文件名
            new_filename = os.path.join('./','new'+fn)
            
            recvd_size = 0
            fp = open(new_filename,'wb')
            while not recvd_size == filesize:
                if filesize -recvd_size > 1024:
                    data = sock.recv(1024)
                    recvd_size += len(data)
                else:
                    data = sock.recv(1024)
                    recvd_size = filesize
                
                fp.write(data)
            fp.close()
        sock.close()
        break

def main():
    socket_service_file()

if __name__ == "__main__":
    main()
                